package com.sitaoke.stocks.service;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONObject;
import com.sitaoke.stocks.common.CalcUtil;
import com.sitaoke.stocks.common.HttpClientUtil;
import com.sitaoke.stocks.dao.StockDao;
import com.sitaoke.stocks.dao.StockRespository;
import com.sitaoke.stocks.pojo.Stock;
import com.sitaoke.stocks.vo.CalcStock;
import com.sitaoke.stocks.vo.EUIGrid;
import com.sitaoke.stocks.vo.EUIPager;
import com.sitaoke.stocks.vo.NetStockInfo;
import com.sitaoke.stocks.vo.PeriodStock;

@Service
public class StockService {

	@Autowired
	private StockRespository stockRespository;
	
	@Autowired
	private StockDao stockDao;
	
	
	@Transactional
	public Stock save(Stock stock) {
		return stockRespository.save(stock);
	}

	/**
	 * 
	 * 分页列表
	 * @author: wyc
	 * @createTime: 2019年5月31日 上午8:59:01
	 * @history:
	 * @param ePager
	 * @param param
	 * @return EUIGrid
	 */
	public EUIGrid getPagerList(EUIPager ePager, Map<String, Object> param) {
		EUIGrid grid = new EUIGrid();
		grid.setTotal(stockDao.getTotalCount(param));
		grid.setRows(stockDao.getPagerList(ePager,param));
		return grid;
	}

	/**
	 * 
	 * 获取列表
	 * @author: wyc
	 * @createTime: 2019年5月31日 上午8:59:14
	 * @history:
	 * @return List<Stock>
	 */
	public List<Stock> getList() {
		return (List<Stock>) stockRespository.findAllByDisplayOrder();
	}

	
	/**
	 * 
	 * 计算
	 * @author: wyc
	 * @createTime: 2019年5月31日 上午8:58:39
	 * @history:
	 * @param stock
	 * @return CalcStock
	 */
	public CalcStock doCalc(Stock stock,boolean calcFileLine) {
		CalcStock calcStock=new CalcStock();
		calcStock.setId(stock.getId());
		calcStock.setCode(stock.getCode());
		NetStockInfo netStockInfo=getStockInfoFromWsByCode(stock.getCode());
		calcStock.setName(netStockInfo.getName());
		calcStock.setStartPrice(CalcUtil.div(netStockInfo.getStartPrice(), 1, 2));
		calcStock.setYesterdayPrice(CalcUtil.div(netStockInfo.getYesterdayPrice(), 1, 2));
		calcStock.setMaxiPrice(CalcUtil.div(netStockInfo.getMaxiPrice(), 1, 2));
		calcStock.setMiniPrice(CalcUtil.div(netStockInfo.getMiniPrice(), 1, 2));
		//保留2位小数
		calcStock.setCurrentPrice(CalcUtil.div(netStockInfo.getCurrentPrice(), 1, 2));
		if(calcFileLine){
			calcStock.setCurrentFiveDayPrice(getFiveLine(stock.getCode()));
			calcStock.setTomorrowFiveDayPrice(getTomrrowFiveLine(stock.getCode()));
		}
		
		
		if(!(stock.getCode().indexOf("000001")>-1)){
			//大多情况
			//当日盈亏比率 dayFlPercent=(currentPrice-yesterdayPrice)/yesterdayPrice
			calcStock.setDayFlPercent(CalcUtil.mul(CalcUtil.div(CalcUtil.sub(calcStock.getCurrentPrice(), calcStock.getYesterdayPrice()), netStockInfo.getYesterdayPrice(),5), 100));
			// 每手当日盈亏( Floating Loss) dayFL=currentPrice-yesterdayPrice
			calcStock.setDayFl(CalcUtil.mul(CalcUtil.sub(calcStock.getCurrentPrice(), calcStock.getYesterdayPrice()), 100));
			//买入价
			calcStock.setBuyPrice(stock.getBuyPrice());
			//买入数量
			calcStock.setBuyCount(stock.getBuyCount());
			// 当日总盈亏 daySumFL=(currentPrice-yesterdayPrice)*buyCount
			calcStock.setDaySumFl(CalcUtil.mul(calcStock.getDayFl(), stock.getBuyCount()));
			//总盈亏 （currentPrice-buyPrice）*buyCount
			calcStock.setSumFl(CalcUtil.mul(CalcUtil.sub(calcStock.getCurrentPrice(), calcStock.getBuyPrice()), stock.getBuyCount()*100));
			//总的盈亏比率（ currentPrice-buyPrice）/buyPrice
			calcStock.setFlPercent(CalcUtil.mul(CalcUtil.div(CalcUtil.sub(calcStock.getCurrentPrice(), calcStock.getBuyPrice()), calcStock.getBuyPrice(),5), 100));
		}else{
			//如果是上证指数
			//当日盈亏比率 dayFlPercent=(currentPrice-yesterdayPrice)/yesterdayPrice
			calcStock.setDayFlPercent(CalcUtil.mul(CalcUtil.div(CalcUtil.sub(calcStock.getCurrentPrice(), calcStock.getYesterdayPrice()), netStockInfo.getYesterdayPrice(),4), 100));
			// 每手当日盈亏( Floating Loss) dayFL=currentPrice-yesterdayPrice
			calcStock.setDayFl(CalcUtil.sub(calcStock.getCurrentPrice(), calcStock.getYesterdayPrice()));
			//买入价
			calcStock.setBuyPrice(Double.valueOf("0"));
			//买入数量
			calcStock.setBuyCount(0);
			// 当日总盈亏 daySumFL=(currentPrice-yesterdayPrice)*buyCount
			calcStock.setDaySumFl(Double.valueOf("0"));
			//总盈亏 （currentPrice-buyPrice）*buyCount
			calcStock.setSumFl(Double.valueOf("0"));
			//总的盈亏比率（ currentPrice-buyPrice）/buyPrice
			calcStock.setFlPercent(Double.valueOf("0"));
		}
		return calcStock;
	}

	/**
	 * 
	 * 调用接口获取数据
	 * @author: wyc
	 * @createTime: 2019年5月30日 下午3:48:09
	 * @history:
	 * @param code
	 * @return NetStockInfo
	 */
	public NetStockInfo getStockInfoFromWsByCode(String code) {
		//http://hq.sinajs.cn/list=sh600585
		//var hq_str_sh600585="海螺水泥,39.710,39.790,39.280,39.780,39.110,39.270,39.280
		//0：”大秦铁路”，股票名字；
		//1：”27.55″，今日开盘价；
		//2：”27.25″，昨日收盘价；
		//3：”26.91″，当前价格；
		///4：”27.55″，今日最高价；
		//5：”26.20″，今日最低价；
		
		String url="http://hq.sinajs.cn/list="+code;
		String result=HttpClientUtil.getInstance().sendHttpGet(url);
		String[] resultArray = result.split(",");
		NetStockInfo netStockInfo=new NetStockInfo();
		if(resultArray.length>1){
			netStockInfo.setCode(code);
			String nameStr=resultArray[0];
			netStockInfo.setName(resultArray[0].substring(nameStr.indexOf("\"") + 1, nameStr.length()));
			netStockInfo.setStartPrice(Double.valueOf(resultArray[1].toString()));
			netStockInfo.setYesterdayPrice(Double.valueOf(resultArray[2].toString()));
			netStockInfo.setCurrentPrice(Double.valueOf(resultArray[3].toString()));
			netStockInfo.setMaxiPrice(Double.valueOf(resultArray[4].toString()));
			netStockInfo.setMiniPrice(Double.valueOf(resultArray[5].toString()));
		}else{
			netStockInfo.setName("ERROR");
		}
		return netStockInfo;
		
	}

	@Deprecated
	public List<PeriodStock> getFiveDayList(String code) {
		//每天4个数据点
		String url=MessageFormat.format("http://money.finance.sina.com.cn/quotes_service/api/json_v2.php/CN_MarketData.getKLineData?symbol={0}&scale=60&ma=60&datalen=20",code);
		String result=HttpClientUtil.getInstance().sendHttpGet(url);
		//JSONArray jsonArray = JSONArray.parseArray(result);
		List<PeriodStock> list = JSONObject.parseArray(result, PeriodStock.class);
		List<PeriodStock> closeList=new ArrayList<PeriodStock>();
		for (PeriodStock periodStock : list) {
			if(periodStock.getDay().contains("15:00:00")){
				closeList.add(periodStock);
			}
		}
		
		Double closeSum=Double.valueOf(0);
		Double closeSumTomorrow=Double.valueOf(0);
		for (int i=0;i<closeList.size();i++) {
			PeriodStock closeStock=closeList.get(i);
			System.out.println(closeStock.getDay()+"--"+closeStock.getClose());
			//5天的总和
			closeSum=CalcUtil.add(closeSum, Double.valueOf(closeStock.getClose()));
			//前4天的总和，第1天不要
			if(i>0){
				closeSumTomorrow=CalcUtil.add(closeSumTomorrow, Double.valueOf(closeStock.getClose()));
			}
			
		}
		//前5天的收盘价的平均价
		System.out.println("closeSum"+closeSum+"-"+CalcUtil.div(closeSum, 5, 3));
		//前4天总和+今天
		closeSumTomorrow=CalcUtil.add(closeSumTomorrow,Double.valueOf(closeList.get(closeList.size()-1).getClose()));
		System.out.println("closeSumTomorrow"+closeSumTomorrow+"-"+CalcUtil.div(closeSumTomorrow, 5, 3));
		
		return closeList;
	}

	
	
	/**
	 * 
	 * 获取5天前的收盘价
	 * @author: wyc
	 * @createTime: 2019年6月1日 下午9:38:09
	 * @history:
	 * @param code void
	 * @return 
	 */
	public Double getFiveDayBeforeClose(String code) {
		// 每天4个数据点
		String url = MessageFormat.format("http://money.finance.sina.com.cn/quotes_service/api/json_v2.php/CN_MarketData.getKLineData?symbol={0}&scale=60&ma=60&datalen=20",code);
		String result = HttpClientUtil.getInstance().sendHttpGet(url);
		List<PeriodStock> list = JSONObject.parseArray(result, PeriodStock.class);
		List<PeriodStock> closeList = new ArrayList<PeriodStock>();
		for (PeriodStock periodStock : list) {
			if (periodStock.getDay().contains("15:00:00")) {
				closeList.add(periodStock);
			}
		}
		Double fiveDayBeforeClose =  Double.valueOf(closeList.get(0).getClose());
		return fiveDayBeforeClose;
	}
	
	
	public Double getCurrentPrice(String code) {
		String url="http://hq.sinajs.cn/list="+code;
		String result=HttpClientUtil.getInstance().sendHttpGet(url);
		String[] resultArray = result.split(",");
		return Double.valueOf(resultArray[3].toString());
	}

	@Deprecated
	public Object getTomorrowFiveDayPrice(String code) {
		//明日5日线=(当前价-5天前Close)/5+今天的5日价
		return CalcUtil.add(getCurrentFivePrice(code), CalcUtil.div(CalcUtil.sub(getCurrentPrice(code), getFiveDayBeforeClose(code)), 5, 3));
	}

	/**
	 * 
	 * 当前的5日均线
	 * @author: wyc
	 * @createTime: 2019年6月1日 下午9:58:29
	 * @history:
	 * @param code
	 * @return double
	 */
	public double getCurrentFivePrice(String code) {
		List<PeriodStock> fiveDayCloseList=getFiveDayBeforeCloseList(code);
		Double closeSumTomorrow=Double.valueOf(0);
		for(int i=0;i<fiveDayCloseList.size();i++){
			PeriodStock closeStock=fiveDayCloseList.get(i);
			if(i>0&&i<fiveDayCloseList.size()-1){
				//5天前不要，今天不要
				System.out.println("getCurrentFivePrice:"+closeStock.getDay()+"--"+closeStock.getClose());
				closeSumTomorrow=CalcUtil.add(closeSumTomorrow, Double.valueOf(closeStock.getClose()));
			}
		}
		return CalcUtil.div(CalcUtil.add(CalcUtil.add(closeSumTomorrow, getCurrentPrice(code)),getCurrentPrice(code)), 5,3);
	}

	/**
	 * 
	 * 获取前5天的收盘价格列表
	 * @author: wyc
	 * @createTime: 2019年6月1日 下午9:59:52
	 * @history:
	 * @param code void
	 * @return 
	 */
	private List<PeriodStock> getFiveDayBeforeCloseList(String code) {
		String url=MessageFormat.format("http://money.finance.sina.com.cn/quotes_service/api/json_v2.php/CN_MarketData.getKLineData?symbol={0}&scale=60&ma=60&datalen=20",code);
		String result=HttpClientUtil.getInstance().sendHttpGet(url);
		//JSONArray jsonArray = JSONArray.parseArray(result);
		List<PeriodStock> list = JSONObject.parseArray(result, PeriodStock.class);
		List<PeriodStock> closeList=new ArrayList<PeriodStock>();
		for (PeriodStock periodStock : list) {
			if(periodStock.getDay().contains("15:00:00")){
				closeList.add(periodStock);
			}
		}
		
		return closeList;
		
	}

	public Object getTomrrowFivePrice(String code) {
		List<PeriodStock> fiveDayCloseList=getFiveDayBeforeCloseList(code);
		Double closeSumTomorrow=Double.valueOf(0);
		for(int i=0;i<fiveDayCloseList.size();i++){
			PeriodStock closeStock=fiveDayCloseList.get(i);
			if(i>0&&i<fiveDayCloseList.size()-1){
				//5天前不要，今天不要
				System.out.println("getCurrentFivePrice:"+closeStock.getDay()+"--"+closeStock.getClose());
				closeSumTomorrow=CalcUtil.add(closeSumTomorrow, Double.valueOf(closeStock.getClose()));
			}
		}
		return CalcUtil.div(CalcUtil.add(CalcUtil.add(closeSumTomorrow, getCurrentPrice(code)),getCurrentPrice(code)), 5,3);
	}
	
	/**
	 * 
	 * 最近5天的收盘时间
	 * @author: wyc
	 * @createTime: 2019年6月1日 下午10:58:26
	 * @history:
	 * @return List<String>
	 */
	@Deprecated
	public List<String> getFiveDayCloseTime(){
		List<String> list=new ArrayList<String>();
		DateTime now = new DateTime(new Date());
		int index=now.getDayOfWeek();
		System.out.println(index);
		int start=index-5;
		int end=index-1;
		
		for(int i=start;i<=end;i++){
			DateTime dt = new DateTime(new Date());
			DateTime closeDt = new DateTime(dt.getYear(),dt.getMonthOfYear(),dt.getDayOfMonth(),15,0,0);
			DateTime beforeDt=closeDt.minusDays(i);
			list.add(beforeDt.toString("yyyy-MM-dd HH:mm:ss"));
		}
		return list;
	}
	
	
	/**
	 * 
	 * 获取需要计算的3天收盘时间(除头去尾)-用于计算明天的5日线
	 * @author: wyc
	 * @createTime: 2019年6月1日 下午10:58:26
	 * @history:
	 * @return List<String>
	 */
	public List<String> getCalThreeDayCloseTime(){
		List<String> list=new ArrayList<String>();
		int sum=0;
		int start=0;
		DateTime now = new DateTime(new Date());
		//15点以前,获取前一天;15点以后，获取当天的收盘
		if(now.getHourOfDay()<15){
			start=1;
		}
		for(int i=start;i<=7;i++){
			DateTime dt = new DateTime(new Date());
			DateTime closeDt = new DateTime(dt.getYear(),dt.getMonthOfYear(),dt.getDayOfMonth(),15,0,0);
			DateTime beforeDt=closeDt.minusDays(i);
			//周六，周日 除外
			if(beforeDt.getDayOfWeek()<6){
				list.add(beforeDt.toString("yyyy-MM-dd HH:mm:ss"));
				sum++;
				if(sum>=3){
					break;
				}
			}
		}
		return list;
	}

	/**
	 * 
	 * 获取需要计算的4天收盘时间(去尾)-用于计算今天实时的5日线
	 * @author: wyc
	 * @createTime: 2019年6月1日 下午11:25:35
	 * @history:
	 * @return Object
	 */
	public List<String> getCalFourDayCloseTime() {
		List<String> list=new ArrayList<String>();
		int sum=0;
		int start=0;
		DateTime now = new DateTime(new Date());
		//15点以前,获取前一天;15点以后，获取当天的收盘
		if(now.getHourOfDay()<15){
			start=1;
		}
		for(int i=start;i<=7;i++){
			DateTime dt = new DateTime(new Date());
			DateTime closeDt = new DateTime(dt.getYear(),dt.getMonthOfYear(),dt.getDayOfMonth(),15,0,0);
			DateTime beforeDt=closeDt.minusDays(i);
			if(beforeDt.getDayOfWeek()<6){
				list.add(beforeDt.toString("yyyy-MM-dd HH:mm:ss"));
				sum++;
				if(sum>=4){
					break;
				}
			}
		}
		return list;
	}

	/**
	 * 
	 * 今日五日线
	 * @author: wyc
	 * @createTime: 2019年6月3日 上午10:25:08
	 * @history:
	 * @param code
	 * @return Double
	 */
	public Double getFiveLine(String code) {
		String url=MessageFormat.format("http://money.finance.sina.com.cn/quotes_service/api/json_v2.php/CN_MarketData.getKLineData?symbol={0}&scale=60&ma=60&datalen=20",code);
		String result=HttpClientUtil.getInstance().sendHttpGet(url);
		List<PeriodStock> list = JSONObject.parseArray(result, PeriodStock.class);
		List<PeriodStock> closeList=new ArrayList<PeriodStock>();
		List<String> fourDayTimeList=getCalFourDayCloseTime();
		for (PeriodStock periodStock:list) {
			for(int j=0;j<fourDayTimeList.size();j++){
				if(periodStock.getDay().equals(fourDayTimeList.get(j))){
					System.out.println(periodStock.getDay()+"-"+periodStock.getClose());
					closeList.add(periodStock);
				}
			}
		}
		Double closeSum=Double.valueOf(0);
		for (PeriodStock closePeriodStock : closeList) {
			closeSum=CalcUtil.add(closeSum, Double.valueOf(closePeriodStock.getClose()));
		}
		return CalcUtil.div(CalcUtil.add(closeSum, getCurrentPrice(code)), 5,3);
	}

	/**
	 * 
	 * 明日五日线
	 * @author: wyc
	 * @createTime: 2019年6月3日 上午10:25:20
	 * @history:
	 * @param code
	 * @return Object
	 */
	public Double getTomrrowFiveLine(String code) {
		String url=MessageFormat.format("http://money.finance.sina.com.cn/quotes_service/api/json_v2.php/CN_MarketData.getKLineData?symbol={0}&scale=60&ma=60&datalen=20",code);
		String result=HttpClientUtil.getInstance().sendHttpGet(url);
		List<PeriodStock> list = JSONObject.parseArray(result, PeriodStock.class);
		Double closeSum=Double.valueOf(0);
		List<String> fourDayTimeList=getCalFourDayCloseTime();
		for (PeriodStock periodStock:list) {
			//获取3天
			for(int j=0;j<fourDayTimeList.size()-1;j++){
				if(periodStock.getDay().equals(fourDayTimeList.get(j))){
					System.out.println(periodStock.getDay()+"-"+periodStock.getClose());
					closeSum=CalcUtil.add(closeSum, Double.valueOf(periodStock.getClose()));
				}
			}
		}
		closeSum=CalcUtil.div(CalcUtil.add(closeSum, CalcUtil.mul(Double.valueOf(getCurrentPrice(code)), 2)), 5, 3);
		return closeSum;
	}

	/**
	 * 
	 * 根据Id获取信息
	 * @author: wyc
	 * @createTime: 2019年6月4日 下午2:12:56
	 * @history:
	 * @param id
	 * @return Stock
	 */
	public Stock getStockById(String id) {
		return stockRespository.findOne(id);
	}

	/**
	 * 
	 * 删除操作
	 * @author: wyc
	 * @createTime: 2019年6月17日 下午3:05:09
	 * @history:
	 * @param id void
	 */
	public void delete(String id) {
		stockRespository.delete(id);
	}
	
}